题目描述:
Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
请你实现 Trie 类:
Trie()
初始化前缀树对象。void insert(String word)
向前缀树中插入字符串word
。boolean search(String word)
如果字符串word
在前缀树中,返回true
(即,在检索之前已经插入);否则,返回false
。boolean startsWith(String prefix)
如果之前已经插入的字符串word
的前缀之一为prefix
,返回true
;否则,返回false
。
示例:
1 | 输入 |
提示:
1 <= word.length, prefix.length <= 2000
word
和prefix
仅由小写英文字母组成insert
、search
和startsWith
调用次数 总计 不超过 $3 * 10^4$ 次
链接:
https://leetcode-cn.com/problems/implement-trie-prefix-tree
题目分析
前缀树是一种树形数据结构,每个字母应该是一个结点,则它的子结点最多有 26 个(也即 26 个字母)。并且我们需要一个布尔变量 isEnd
标记该结点是否是字符串终点。以下分别是前缀数的三种操作:
- 插入。我们按照单词的字母顺序从树的根部开始搜索。
- 如果字母存在于当前结点的子结点中,则移动到该子结点,继续下一个字母的搜索。
- 如果字母不存在于当前结点的子结点中,则创建新的子结点,继续处理下一个字母。
- 完成插入后,需要将最后一个结点的
isEnd
标记为true
,表示该结点是一个字符串的终点。
- 搜索。我们按照单词的字母顺序从树的根部开始搜索。
- 如果字母存在于当前结点的子结点中,则移动到该子结点,继续下一个字母的搜索。
- 如果字母不存在于当前结点的子节结点中,则说明该字符串不存在于前缀树中,直接返回
false
。 - 完成搜索后,检查该结点是否是字符串的终点(
isEnd
是否为true
),是则说明该字符串存在于前缀树中,返回true
,反之返回false
。
- 搜索前缀。我们按照单词的字母顺序从树的根部开始搜索。
- 如果字母存在于当前结点的子结点中,则移动到该子结点,继续下一个字母的搜索。
- 如果字母不存在于当前结点的子节结点中,则说明该前缀不存在于前缀树中,直接返回
false
。 - 完成搜索后,返回
true
,表示该前缀存在于前缀树中。
1 | class Trie { |
时间复杂度:$O(n)$,其中 $n$ 是每次操作字符串的长度。初始化的复杂度是 $O(1)$,而对于每次操作(包括插入和搜索),我们都需要按照字符串进行搜索,搜索的深度就是字符串的长度。
空间复杂度:$O(T)$,其中 $T$ 是结点的数目。每一个结点含有大小为 26 的指针数组和一个布尔变量。